﻿using System;
using System.IO;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.ComponentModel;
using CSBackup_Web.Sources.Override;

namespace CSBackup_Web.Sources.Override
{
    public static class BackupRecovery
    {

        /// <summary>
        /// 恢复整个还原点备份还原函数
        /// </summary>
        /// <param name="selectedBackupLocation">备份文件位置</param>
        /// <param name="backupType">备份类型</param>
        /// <param name="backupUnit">备份单元</param>
        /// <param name="dependBackup">依赖的备份路径</param>
        /// <param name="recoveryPath">恢复目录</param>
        /// <param name="projectInfoPath">项目路径</param>
        /// <param name="autoSep">自动备份</param>
        /// <param name="retainSecAttributeArg">未知</param>
        /// <returns>0 fail，1 success</returns>

        [DllImport("SecureAutoBackup.dll", EntryPoint = "TFO_Recovery", CharSet = CharSet.Ansi, CallingConvention=CallingConvention.StdCall)]
        public static extern int Recovery(string selectedBackupLocation, string backupType, string backupUnit, string dependBackup, string recoveryPath, string projectInfoPath, int autoSep, int retainSecAttributeArg);


        /// <summary>
        /// 恢复部分文件
        /// </summary>
        /// <param name="selectedBackupLocation">备份文件位置</param>
        /// <param name="backupType">备份类型</param>
        /// <param name="backupUnit">备份单元</param>
        /// <param name="dependBackup">依赖的备份路径</param>
        /// <param name="recoveryPath">恢复目录</param>
        /// <param name="projectInfoPath">项目路径</param>
        /// <param name="autoSep">自动备份</param>
        /// <param name="retainSecAttributeArg">未知</param>
        /// <param name="fileList">要恢复的文件列表</param>
        /// <param name="fileListNum">要恢复的文件列表长度</param>
        /// <param name="dirList">要恢复的目录列表</param>
        /// <param name="dirListNum">要恢复的目录列表长度</param>
        /// <param name="difList">要恢复的查分文件的位置</param>
        /// <returns>0 fail，1 success </returns>
        [DllImport("SecureAutoBackup.dll", EntryPoint = "TFO_RecoveryPartFile", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
        public static extern int RecoveryPartFiles(string selectedBackupLocation, string backupType, string backupUnit,
            string dependBackup, string recoveryPath, string projectInfoPath, int autoSep, int retainSecAttributeArg,
            string[] fileList, int fileListNum, string[] dirList, int dirListNum, string[] difList);

        /// <summary>
        /// 导出自分离同步函数
        /// </summary>
        /// <param name="prjPath">工程文件路径</param>
        /// <returns>0 -- 同步失败 ；1 -- 同步成功</returns>
        [DllImport("SecureAutoBackup.dll", EntryPoint = "TAS_SyncAutosep", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
        public static extern int SyncSelfSep(string prjPath);

        /// <summary>
        /// 导出删除整个还原点的函数
        /// </summary>
        /// <param name="prjPath">工程文件夹路径</param>
        /// <param name="bkpPath">待删除的备份路径</param>
        /// <param name="bkpName">待删除的备份名字</param>
        /// <returns>大于0删除成功，否则删除失败</returns>
        [DllImport("SecureAutoBackup.dll", EntryPoint = "TR_DelRecoveryPoint", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
        public static extern int DelRecoveryPoint(string prjPath, string bkpPath, string bkpName);

        /// <summary>
        /// 恢复部分还原点工作实际执行逻辑
        /// </summary>
        /// <param name="backupinfo"></param>
        public static void RecoveryPartRecoveryPoint(List<string> fileList, string projPath, BackupInfo backupinfo)
        {
            string selectedBackupLocation = backupinfo.BkpLocation;//选中的还原点文件位置
            string backupType = backupinfo.BkpType;//备份类型
            string backupUnit = backupinfo.BkpUnit;//备份单元
            string dependBackup = backupinfo.BkpDepended;//依赖的备份
            string recoveryPath = Path.Combine(Path.GetDirectoryName(projPath), "Recover");//恢复路径
            if (!Directory.Exists(recoveryPath))
                Directory.CreateDirectory(recoveryPath);
            string projectInfoPath = projPath;//项目信息路径
            int autoSep = 0;//自动备份间隔
            int retainSecAttributeArg = 0;//未知
            List<string> dirList = new List<string>();
            List<string> difList = new List<string>();

            //还原部分文件函数
            try
            {
                BackupRecovery.RecoveryPartFiles(selectedBackupLocation,
                backupType,
                backupUnit,
                dependBackup,
                recoveryPath,
                projectInfoPath,
                autoSep,
                retainSecAttributeArg,
                fileList.ToArray(),
                fileList.Count,
                dirList.ToArray(),
                dirList.Count,
                difList.ToArray());
            }
            catch (Exception exp)
            {
                throw new Exception(exp.Message);
            }
        }


        /// <summary>
        /// 恢复整个还原点工作实际执行逻辑
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        static public void RecoveryWholeRecoveryPoint(string projPath, BackupInfo backupInfo)
        {
            string selectedBackupLocation = backupInfo.BkpLocation;//选中的还原点文件位置
            string backupType = backupInfo.BkpType;//备份类型
            string backupUnit = backupInfo.BkpUnit;//备份单元
            string dependBackup = backupInfo.BkpDepended;//依赖的备份
            string recoveryPath = Path.Combine(Path.GetDirectoryName(projPath), "Recover");//恢复路径
            if (!Directory.Exists(recoveryPath))
                Directory.CreateDirectory(recoveryPath);
            string projectInfoPath = projPath;//项目信息路径
            int autoSep = 0;//自动备份间隔
            int retainSecAttributeArg = 0;//未知
            //还原整个还原点函数
            try
            {
                BackupRecovery.Recovery(selectedBackupLocation,
                backupType,
                backupUnit,
                dependBackup,
                recoveryPath,
                projectInfoPath,
                autoSep,
                retainSecAttributeArg);
            }
            catch (Exception exp)
            {
                throw new Exception(exp.Message);
            }
        }
    }
}
